package com.ehcache.service;

import com.ehcache.model.Customer;
import com.utils.HibernateUtil;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.jdbc.Work;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Iterator;

public class BusinessService {
    public static SessionFactory sessionFactory = new HibernateUtil().getSessionFactory();

    private void batchUpdateCustomer1() {
        Session session = sessionFactory.openSession();
        Transaction tx = null;
        try {
            tx = session.beginTransaction();
            Iterator customers = session.createQuery("from Customer c where c.age>0")
                    .list().iterator();


            while (customers.hasNext()) {
                Customer customer = (Customer) customers.next();
                customer.setAge(customer.getAge() + 1);
                session.flush();
                session.evict(customer);
            }
            tx.commit();
        } catch (RuntimeException e) {
            if (tx != null) {
                tx.rollback();
            }
            throw e;
        } finally {
            session.close();
        }
    }

    private void batchUpdateCustomer2() throws Exception {
        Session session = sessionFactory.openSession();
        Transaction tx = null;
        try {
            tx = session.beginTransaction();

            Work work = new Work() {
                @Override
                public void execute(Connection connection) throws SQLException {
                    PreparedStatement stmt = connection.prepareStatement("UPDATE CUSTOMERS SET AGE=AGE+1 WHERE AGE>0 ");
                    stmt.executeUpdate();
                }
            };
            session.doWork(work);
            tx.commit();

        } catch (Exception e) {
            if (tx != null) {
                tx.rollback();
            }
            throw e;
        } finally {
            session.close();
        }
    }

    private void useQueryCache() {
        Session session = sessionFactory.openSession();
        Transaction tx = null;
        try {
            tx = session.beginTransaction();
            Query customerByAgeQuery = session.createQuery("from Customer c where c.age>:age");
            customerByAgeQuery.setInteger("age", 0);
            customerByAgeQuery.setCacheable(true);
            customerByAgeQuery.setCacheRegion("customerQueries");

            for (int i = 0; i < 10; i++) {
                customerByAgeQuery.list();
            }
            tx.commit();
        } catch (RuntimeException e) {
            if (tx != null) {
                tx.rollback();
            }
            throw e;
        } finally {
            session.close();
        }
    }

    private void test() throws Exception {
        batchUpdateCustomer1();
        batchUpdateCustomer2();
        useQueryCache();
    }

    public static void main(String args[]) throws Exception {
        new BusinessService().test();
        Thread.sleep(60000);
        sessionFactory.close();
    }
}
